﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.OleDb;
using NLog;
using Aandelendelen.Obs;
using Aandelendelen.Db;
using Aandelendelen.Mail;

namespace Aandelendelen.Payment
{
	public class IdealTargetPayHandler
	{
		private static Logger logger = LogManager.GetCurrentClassLogger();

		const string subAccount = "57429";
		string transactionId = null;

		public IdealTargetPayHandler(string transactionId, bool check)
		{
			if (string.IsNullOrEmpty(transactionId))
				throw new Exception("No transactionID");

			this.transactionId = transactionId;
			logger.Debug("Transaction: {0}", transactionId);

			if (check)
			{
				if (this.IsTargetPayReferrer() == false)
				{
					throw new Exception("Referrer not from TargetPay");
				}
			}
		}

		private bool IsTargetPayReferrer()
		{

			string ip = ObjectFormatter.CurrentIp;
			if (ip == null)
				return false;

			string[] ipComponents = ip.Split('.');

			try
			{
				if (ipComponents[0] == "89" && ipComponents[1] == "184" && ipComponents[2] == "168")
				{
					//int num = Convert.ToInt32(ipComponents[3]);
					//if (num >= 80 && num <= 86)
					return true;
				}
			}
			catch
			{
				return false;
			}

			return false;
		}

		public void Handle()
		{
			Query existsQuery = new Query("s_micropayment", "transactionid", this.transactionId, OleDbType.Char);

			ResultSet resultSet = (ResultSet)existsQuery.Execute();

			bool payed = false;

			if (resultSet.Count > 0)
			{
				payed = (bool)resultSet[0, "Payed"];
			}
			else
			{
				throw new Exception("ERROR: iDEAL transaction " + transactionId + " not found.");
			}

			if (!payed)
			{
				logger.Info("Initiating check...");
				IdealCheck idealCheck = new IdealCheck(IdealTargetPayHandler.subAccount, transactionId);
				if (idealCheck.Error)
				{
					throw new Exception(idealCheck.ErrorMessage);
				}

				if (idealCheck.Payed)
				{
					logger.Info("Payed!");
					int nawId = (int)resultSet[0, "NawId"];

					Query nawQuery = new Query("s_getemailfromid", "id", nawId, OleDbType.Integer);
					ResultSet nawResultSet = (ResultSet)nawQuery.Execute();

					if (nawResultSet.Count == 0)
						return;

					Query query = new Query("sp_updatemicropaymentpayed", "transactionid", transactionId, OleDbType.Char);
					query.Execute();

					decimal amount = (decimal)resultSet[0, "Amount"];

					this.InsertMutation(nawId, amount);

					this.SendConfirmationMail(amount, nawResultSet);
				}
				else
				{
					logger.Info("Not payed!");
				}
			}
			else
			{
				logger.Info("Already payed");
			}
		}

		private void InsertMutation(int userId, decimal amount)
		{
			CommonQueries.InsertSaldoMutation(userId, amount, 2, 0);
		}

		private void SendConfirmationMail(decimal amount, ResultSet resultSet)
		{
			Userinfo userInfo = new Userinfo(resultSet, false);

			MailArguments mailArgs = MailArguments.MailArgs;
			mailArgs.Clear();

			logger.Info("iDEAL transaction successful. User: {0}, amount {1}", userInfo.FullName, ObjectFormatter.GetCurrencyString(amount));

			mailArgs["{oldsaldo}"] = ObjectFormatter.GetCurrencyString(userInfo.Saldo - amount);
			mailArgs["{newsaldo}"] = ObjectFormatter.GetCurrencyString(userInfo.Saldo);
			mailArgs["{aanhef}"] = userInfo.MailAanhef;
			mailArgs["{username}"] = userInfo.Gebruikersnaam;
			mailArgs["{amount}"] = ObjectFormatter.GetCurrencyString(amount);
			mailArgs["{reason}"] = "storting via iDEAL";

			EMail email = MailCache.GetMail("balancechanged");
			email.Bcc = true;
			email.Recipients = userInfo.Email;

			email.QueueSingle();
		}

	}
}